package sistemadeproyectos;

import java.net.*;
import java.io.*;
import java.util.*;
import java.text.StringCharacterIterator;

/**
 * @author Angel Rubio, 06-40263
 * @author Antonio Mundo, 06-39956
 * @author Giancarlo Nebiolo, 06-39965
 * @version 3.0
 */

public class ChatServidor extends Thread{
    
    private ServerSocket serverSocket = null;
    private LinkedList <AdminChat_thr> hilosChat = new LinkedList<AdminChat_thr>();
    private boolean continuar = true;
    
    /**
     * Nombre: die(String error)
     * Descripcion: Imprime algun mensaje de error, y termina el programa
     * @param error  mensaje de error a imprimir
     */
    public static void die(String error){
        System.err.println(error);
        System.exit(-1);
    }
    
    public int NumUsuarios(){
        return this.hilosChat.size();
    }
    
    private void revisarLista(){
        int i = 0;
        while(i < hilosChat.size()){
            if(!(hilosChat.get(i).isAlive())){
                hilosChat.remove(i);
            }
            else{
                i++;
            }
        }
    }
    
    public void cerrar(){
        this.continuar = false;
        System.out.println("Cerrando chat servidor...");
        try{
            for(int i = 0; i < hilosChat.size(); i++){
                hilosChat.get(i).cerrar();
            }
            this.serverSocket.close();
        }
        catch(SocketException se){
            se.printStackTrace();
        }
        catch(IOException ioe){
            ioe.printStackTrace();
        }
    }
      
    /**
     * Nombre: esEntero(String cad) 
     * Descripcion: Verifica si una cadena de caracteres forma un entero
     * @param cad   cadena a evaluar
     * @return Verdadero si forma un entero, falso en caso contrario
     */
    public static boolean esEntero(String cad){
        for(int i = 0; i<cad.length(); i++){
            if( !Character.isDigit(cad.charAt(i))){
                return false;
            }
        }
        return true;
    }
        
    /**
     * Nombre: esEntero(String cad) 
     * Descripcion: Verifica si un string esta conformado por una cadena de caracteres alfa numericos
     * @param IDNodo cadena a evaluar
     * @return Verdadero si esta conformado por una cadena de caracteres alfa numericos, falso en caso contrario
     */
    public static boolean isAlfanum(String IDNodo){
        boolean Num_Letra = true;
        StringCharacterIterator verif = new StringCharacterIterator(IDNodo);
        for (char ch=verif.first(); ch != StringCharacterIterator.DONE; ch=verif.next()) {
        if (Character.isLetterOrDigit(ch) == false){
            Num_Letra = false; break; }	
        }
        return Num_Letra;
    }
          
    /**
     * Funcion principal de los nodos. Se verificaran que los parametros sean 
     * introducidos correctamente, se lee la biblioteca y el archivo, se escuchan
     * las solicitudes de clientes y se asigna un hilo por cada solicitud (request)
     * que se le haga al nodo (servidor)
     */    
    public void run(){
        Hashtable<String, Hashtable<String, Chatroom>> listChatrooms;
        listChatrooms = new Hashtable<String, Hashtable<String, Chatroom>>();
        ServersConf rutas = new ServersConf();
        int puerto = rutas.getPuertoChat();
        System.out.println("\n\nInicializando Servidor...");
        try {
            this.serverSocket = new ServerSocket(puerto); 
        } 
        catch (IOException e){
            die("No se pudo escuchar en el puerto "+puerto+": "+e.getMessage()); 
        }
        System.out.println("Servidor en espera de conexiones de clientes");
        try {
            System.out.println("\tIp del Servidor: "+ InetAddress.getLocalHost()); 
        }
        catch (UnknownHostException e){
            System.out.println("\tProblemas al detectar IP de Servidor."); 
        }
        System.out.println("\tPuerto de escucha: "+ puerto);
        /**Se crean los hilos para atender a los clientes que se conecten*/
        while (continuar){
            try{
                revisarLista();
                AdminChat_thr hiloChat = new AdminChat_thr(this.serverSocket.accept(), listChatrooms);
                hilosChat.add(hiloChat);
                hiloChat.start();
                System.out.println("Se ha conectado un cliente...");
            }
            catch(IOException ioe){
                //System.out.println("Error en el servidor de chat");
                //ioe.printStackTrace();
            }
        }
    }
}